package com.fary.common;

import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Optional;

public class ApiResponse<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    public static final int SUCCESS = 0;
    public static final int FAIL = -1;
    public static final int BUSY = -100;
    public static final String SUCCESS_TEXT = "Success";
    public static final String FAIL_TEXT = "Fail";
    public static final String BUSY_TEXT = "Busy";
    @Getter
    private long status;
    @Setter
    @Getter
    private String message;
    private Long timestamp = System.currentTimeMillis();
    @Setter
    @Getter
    private T data;

    public ApiResponse() {
        this.status = 0L;
        this.message = "Success";
    }

    public ApiResponse(long status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    public ApiResponse(T data) {
        if (data instanceof Exception) {
            this.status = -1L;
            this.message = ((Exception) data).getLocalizedMessage();
        } else {
            this.status = 0L;
            this.message = "Success";
            if (data instanceof Optional) {
                Optional<T> opt = (Optional) data;
                if (opt.isPresent()) {
                    this.data = opt.get();
                }
            } else {
                this.data = data;
            }
        }
    }

    public void setStatus(long status) {
        this.status = status;
        if (status == 0L) {
            this.message = "Success";
        } else if (status == -100L) {
            this.message = "Busy";
        } else {
            this.message = "";
        }
    }

    public long getTimestamp() {
        return this.timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public static <T> ApiResponse<T> ok() {
        return new ApiResponse<T>();
    }

    public static <T> ApiResponse<T> ok(T data) {
        return new ApiResponse<T>(data);
    }

    public static <T> ApiResponse<T> fail(String message) {
        return new ApiResponse<T>(-1L, message, null);
    }

    public static <T> ApiResponse<T> fail(String message, T data) {
        return new ApiResponse<T>(-1L, message, data);
    }
}
